//基本操作支持:至少需要支持标准的键值对插入、查询(包括范围查询)、更新以及删除等基本操作
#pragma once
#ifndef KV_FOUNDATION_HPP
#define KV_FOUNDATION_HPP
#include <sw/redis++/redis++.h>
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <optional>
#include <type_traits>
#include <atomic>
#include "Mutex.hpp"
#include "Log.hpp"

namespace Redis_Foundation_Model {
    using namespace std;
    using namespace Lock_Module;
    using namespace Log_Module;

    class Redis_Client {
    private:
        // 类型转换辅助函数
        template<typename T>
        static string toString(const T& value) {
            if constexpr (is_arithmetic_v<T>) {
                return to_string(value);
            } else if constexpr (is_same_v<T, string>) {
                return value;
            } else {
                return string(value);
            }
        }
    
        template<typename T>
        static T fromString(const string& str) {
            if constexpr (is_same_v<T, string>) {
                return str;
            } else if constexpr (is_integral_v<T>) {
                return stoll(str);
            } else if constexpr (is_floating_point_v<T>) {
                return stod(str);
            } else {
                return T(str);
            }
        }

    public:
        //禁止拷贝
        Redis_Client() = default;
        Redis_Client(const Redis_Client&) = delete;
        Redis_Client& operator=(const Redis_Client&) = delete;

        //连接参数
        struct Connection {
            string host = "127.0.0.1";
            int port = 6379;
            string password;
            int timeout = 1000; //ms
            int pool_size = 10;
        };

        static bool Initialize(const Connection& options) {
            LOG(LogLevel::INFO) << "Initializing Redis client...";
            Lock_Module::LockGuard lock(_instance_mutex);
            _options = options;
        
            sw::redis::ConnectionOptions connection_options;
            connection_options.host = options.host;
            connection_options.port = options.port;
            connection_options.password = options.password;
            connection_options.socket_timeout = std::chrono::milliseconds(options.timeout);

            sw::redis::ConnectionPoolOptions pool_options;
            pool_options.size = options.pool_size;

            _instance = make_shared<Redis_Client>();
            _instance->_redis = make_unique<sw::redis::Redis>(connection_options, pool_options);
            
            // 测试连接
            if (!_instance->ping()) {
                LOG(LogLevel::ERROR) << "Redis ping failed";
                return false;
            }
            LOG(LogLevel::INFO) << "Redis client initialized successfully";
            return true;
        }
    
        static shared_ptr<Redis_Client> GetInstance() {
            LOG(LogLevel::DEBUG) << "Getting Redis client instance";
            Lock_Module::LockGuard lock(_instance_mutex);
            if (!_instance) {
                LOG(LogLevel::WARNING) << "Redis client not initialized, creating default instance";
                _instance = make_shared<Redis_Client>();
            }
            return _instance;
        }

    private:
        static shared_ptr<Redis_Client> _instance;
        static Connection _options;
        static Lock_Module::Mutex _instance_mutex;
        unique_ptr<sw::redis::Redis> _redis;
    
    public:
        //对k_V的通用操作
        vector<string> Keys(const string& pattern) {
            LOG(LogLevel::DEBUG) << "KEYS command - pattern: " << pattern;
            vector<string> result;
            _redis->keys(pattern, back_inserter(result));
            LOG(LogLevel::DEBUG) << "KEYS found " << result.size() << " keys";
            return result;
        }

        bool exists(const string& Key) {
            LOG(LogLevel::DEBUG) << "EXISTS command - key: " << Key;
            bool result = _redis->exists(Key);
            LOG(LogLevel::DEBUG) << "EXISTS result: " << result;
            return result;
        }

        bool del(const string& Key) {
            LOG(LogLevel::DEBUG) << "DEL command - key: " << Key;
            bool result = _redis->del(Key) > 0;
            LOG(LogLevel::DEBUG) << "DEL result: " << result;
            return result;
        }

        bool expire(const string& key, int seconds) {
            LOG(LogLevel::DEBUG) << "EXPIRE command - key: " << key << ", seconds: " << seconds;
            bool result = _redis->expire(key, std::chrono::seconds(seconds));
            LOG(LogLevel::DEBUG) << "EXPIRE result: " << result;
            return result;
        }

        long long ttl(const string& key) {
            LOG(LogLevel::DEBUG) << "TTL command - key: " << key;
            auto ttl_result = _redis->ttl(key);
            long long result = ttl_result ? ttl_result : -1;
            LOG(LogLevel::DEBUG) << "TTL result: " << result;
            return result;
        }

        //字符串操作
        template<typename T>
        bool set(const string& key, const T& value) {
            LOG(LogLevel::DEBUG) << "SET command - key: " << key << ", value: " << toString(value);
            _redis->set(key, toString(value));
            LOG(LogLevel::DEBUG) << "SET completed";
            return true;
        }
    
        template<typename T>
        bool setex(const string& key, int seconds, const T& value) {
            LOG(LogLevel::DEBUG) << "SETEX command - key: " << key << ", seconds: " << seconds << ", value: " << toString(value);
            _redis->setex(key, seconds, toString(value));
            LOG(LogLevel::DEBUG) << "SETEX completed";
            return true;
        }
    
        template<typename T>
        optional<T> get(const string& key) {
            LOG(LogLevel::DEBUG) << "GET command - key: " << key;
            auto result = _redis->get(key);
            LOG(LogLevel::DEBUG) << "GET result: " << (result ? "found" : "not found");
            return result ? optional<T>(fromString<T>(*result)) : nullopt;
        }
    
        template<typename T>
        bool setnx(const string& key, const T& value) {
            LOG(LogLevel::DEBUG) << "SETNX command - key: " << key << ", value: " << toString(value);
            bool result = _redis->setnx(key, toString(value));
            LOG(LogLevel::DEBUG) << "SETNX result: " << result;
            return result;
        }
    
        long long incr(const string& key, long long increment = 1) {
            LOG(LogLevel::DEBUG) << "INCR command - key: " << key << ", increment: " << increment;
            long long result = _redis->incrby(key, increment);
            LOG(LogLevel::DEBUG) << "INCR result: " << result;
            return result;
        }

        double incrbyfloat(const string& key, double increment = 1.0) {
            LOG(LogLevel::DEBUG) << "INCRBYFLOAT command - key: " << key << ", increment: " << increment;
            double result = _redis->incrbyfloat(key, increment);
            LOG(LogLevel::DEBUG) << "INCRBYFLOAT result: " << result;
            return result;
        }

        //哈希操作
        template<typename Field, typename Value>
        bool hset(const string& key, const Field& field, const Value& value) {
            LOG(LogLevel::DEBUG) << "HSET command - key: " << key << ", field: " << toString(field) << ", value: " << toString(value);
            bool result = _redis->hset(key, toString(field), toString(value));
            LOG(LogLevel::DEBUG) << "HSET result: " << result;
            return result;
        }
    
        template<typename Field, typename Value>
        bool hset(const string& key, const unordered_map<Field, Value>& field_values) {
            LOG(LogLevel::DEBUG) << "HSET multiple command - key: " << key << ", field count: " << field_values.size();
            unordered_map<string, string> converted;
            for (const auto& item : field_values) {
                converted[toString(item.first)] = toString(item.second);
            }
            _redis->hset(key, converted.begin(), converted.end());
            LOG(LogLevel::DEBUG) << "HSET multiple completed";
            return true;
        }
    
        template<typename T>
        optional<T> hget(const string& key, const string& field) {
            LOG(LogLevel::DEBUG) << "HGET command - key: " << key << ", field: " << field;
            auto result = _redis->hget(key, field);
            LOG(LogLevel::DEBUG) << "HGET result: " << (result ? "found" : "not found");
            return result ? optional<T>(fromString<T>(*result)) : nullopt;
        }
    
        template<typename Field, typename Value>
        unordered_map<string, Value> hgetall(const string& key) {
            LOG(LogLevel::DEBUG) << "HGETALL command - key: " << key;
            unordered_map<string, string> result;
            _redis->hgetall(key, inserter(result, result.begin()));
            LOG(LogLevel::DEBUG) << "HGETALL found " << result.size() << " fields";
            
            unordered_map<string, Value> converted;
            for (const auto& item : result) {
                converted[item.first] = fromString<Value>(item.second);
            }
            return converted;
        }
    
        template<typename Field>
        bool hdel(const string& key, const Field& field) {
            LOG(LogLevel::DEBUG) << "HDEL command - key: " << key << ", field: " << toString(field);
            bool result = _redis->hdel(key, toString(field)) > 0;
            LOG(LogLevel::DEBUG) << "HDEL result: " << result;
            return result;
        }
    
        template<typename Field>
        bool hexists(const string& key, const Field& field) {
            LOG(LogLevel::DEBUG) << "HEXISTS command - key: " << key << ", field: " << toString(field);
            bool result = _redis->hexists(key, toString(field));
            LOG(LogLevel::DEBUG) << "HEXISTS result: " << result;
            return result;
        }
    
        template<typename Field, typename Value>
        bool hmset(const string& key, const unordered_map<Field, Value>& field_values) {
            LOG(LogLevel::DEBUG) << "HMSET command - key: " << key << ", field count: " << field_values.size();
            return hset(key, field_values);
        }
    
        template<typename T>
        vector<optional<T>> hmget(const string& key, const vector<string>& fields) {
            LOG(LogLevel::DEBUG) << "HMGET command - key: " << key << ", field count: " << fields.size();
            vector<optional<string>> results;
            _redis->hmget(key, fields.begin(), fields.end(), back_inserter(results));
            
            vector<optional<T>> converted;
            for (const auto& result : results) {
                if (result) {
                    converted.push_back(fromString<T>(*result));
                } else {
                    converted.push_back(nullopt);
                }
            }
            LOG(LogLevel::DEBUG) << "HMGET completed, found " << converted.size() << " values";
            return converted;
        }

        //列表操作
        template<typename T>
        bool lpush(const string& key, const T& value) {
            LOG(LogLevel::DEBUG) << "LPUSH command - key: " << key << ", value: " << toString(value);
            bool result = _redis->lpush(key, toString(value)) > 0;
            LOG(LogLevel::DEBUG) << "LPUSH result: " << result;
            return result;
        }
    
        template<typename T>
        bool lpush(const string& key, const vector<T>& values) {
            LOG(LogLevel::DEBUG) << "LPUSH multiple command - key: " << key << ", value count: " << values.size();
            vector<string> converted;
            for (const auto& value : values) {
                converted.push_back(toString(value));
            }
            bool result = _redis->lpush(key, converted.begin(), converted.end()) > 0;
            LOG(LogLevel::DEBUG) << "LPUSH multiple result: " << result;
            return result;
        }
    
        template<typename T>
        bool rpush(const string& key, const T& value) {
            LOG(LogLevel::DEBUG) << "RPUSH command - key: " << key << ", value: " << toString(value);
            bool result = _redis->rpush(key, toString(value)) > 0;
            LOG(LogLevel::DEBUG) << "RPUSH result: " << result;
            return result;
        }
    
        template<typename T>
        bool rpush(const string& key, const vector<T>& values) {
            LOG(LogLevel::DEBUG) << "RPUSH multiple command - key: " << key << ", value count: " << values.size();
            vector<string> converted;
            for (const auto& value : values) {
                converted.push_back(toString(value));
            }
            bool result = _redis->rpush(key, converted.begin(), converted.end()) > 0;
            LOG(LogLevel::DEBUG) << "RPUSH multiple result: " << result;
            return result;
        }
    
        template<typename T>
        optional<T> lpop(const string& key) {
            LOG(LogLevel::DEBUG) << "LPOP command - key: " << key;
            auto result = _redis->lpop(key);
            LOG(LogLevel::DEBUG) << "LPOP result: " << (result ? "found" : "not found");
            return result ? optional<T>(fromString<T>(*result)) : nullopt;
        }
    
        template<typename T>
        optional<T> rpop(const string& key) {
            LOG(LogLevel::DEBUG) << "RPOP command - key: " << key;
            auto result = _redis->rpop(key);
            LOG(LogLevel::DEBUG) << "RPOP result: " << (result ? "found" : "not found");
            return result ? optional<T>(fromString<T>(*result)) : nullopt;
        }
    
        template<typename T>
        vector<T> lrange(const string& key, long long start, long long stop) {
            LOG(LogLevel::DEBUG) << "LRANGE command - key: " << key << ", start: " << start << ", stop: " << stop;
            vector<string> results;
            _redis->lrange(key, start, stop, back_inserter(results));
            LOG(LogLevel::DEBUG) << "LRANGE found " << results.size() << " elements";
            
            vector<T> converted;
            for (const auto& result : results) {
                converted.push_back(fromString<T>(result));
            }
            return converted;
        }

        //集合操作
        template<typename T>
        bool sadd(const string& key, const T& member) {
            LOG(LogLevel::DEBUG) << "SADD command - key: " << key << ", member: " << toString(member);
            bool result = _redis->sadd(key, toString(member)) > 0;
            LOG(LogLevel::DEBUG) << "SADD result: " << result;
            return result;
        }
    
        template<typename T>
        bool sadd(const string& key, const vector<T>& members) {
            LOG(LogLevel::DEBUG) << "SADD multiple command - key: " << key << ", member count: " << members.size();
            vector<string> converted;
            for (const auto& member : members) {
                converted.push_back(toString(member));
            }
            bool result = _redis->sadd(key, converted.begin(), converted.end()) > 0;
            LOG(LogLevel::DEBUG) << "SADD multiple result: " << result;
            return result;
        }
    
        template<typename T>
        bool srem(const string& key, const T& member) {
            LOG(LogLevel::DEBUG) << "SREM command - key: " << key << ", member: " << toString(member);
            bool result = _redis->srem(key, toString(member)) > 0;
            LOG(LogLevel::DEBUG) << "SREM result: " << result;
            return result;
        }
    
        template<typename T>
        bool sismember(const string& key, const T& member) {
            LOG(LogLevel::DEBUG) << "SISMEMBER command - key: " << key << ", member: " << toString(member);
            bool result = _redis->sismember(key, toString(member));
            LOG(LogLevel::DEBUG) << "SISMEMBER result: " << result;
            return result;
        }
    
        template<typename T>
        vector<T> smembers(const string& key) {
            LOG(LogLevel::DEBUG) << "SMEMBERS command - key: " << key;
            vector<string> results;
            _redis->smembers(key, back_inserter(results));
            LOG(LogLevel::DEBUG) << "SMEMBERS found " << results.size() << " members";
            
            vector<T> converted;
            for (const auto& result : results) {
                converted.push_back(fromString<T>(result));
            }
            return converted;
        }

        //有序集合操作
        template<typename T>
        bool zadd(const string& key, double score, const T& member) {
            LOG(LogLevel::DEBUG) << "ZADD command - key: " << key << ", score: " << score << ", member: " << toString(member);
            bool result = _redis->zadd(key, toString(member), score) > 0;
            LOG(LogLevel::DEBUG) << "ZADD result: " << result;
            return result;
        }
    
        template<typename T>
        bool zadd(const string& key, const unordered_map<T, double>& member_scores) {
            LOG(LogLevel::DEBUG) << "ZADD multiple command - key: " << key << ", member count: " << member_scores.size();
            unordered_map<string, double> converted;
            for (const auto& item : member_scores) {
                converted[toString(item.first)] = item.second;
            }
            bool result = _redis->zadd(key, converted.begin(), converted.end()) > 0;
            LOG(LogLevel::DEBUG) << "ZADD multiple result: " << result;
            return result;
        }
    
        template<typename T>
        bool zrem(const string& key, const T& member) {
            LOG(LogLevel::DEBUG) << "ZREM command - key: " << key << ", member: " << toString(member);
            bool result = _redis->zrem(key, toString(member)) > 0;
            LOG(LogLevel::DEBUG) << "ZREM result: " << result;
            return result;
        }
    
        template<typename T>
        vector<T> zrange(const string& key, long long start, long long stop) {
            LOG(LogLevel::DEBUG) << "ZRANGE command - key: " << key << ", start: " << start << ", stop: " << stop;
            vector<string> results;
            _redis->zrange(key, start, stop, back_inserter(results));
            LOG(LogLevel::DEBUG) << "ZRANGE found " << results.size() << " members";
            
            vector<T> converted;
            for (const auto& result : results) {
                converted.push_back(fromString<T>(result));
            }
            return converted;
        }
    
        template<typename T>
        vector<T> zrevrange(const string& key, long long start, long long stop) {
            LOG(LogLevel::DEBUG) << "ZREVRANGE command - key: " << key << ", start: " << start << ", stop: " << stop;
            vector<string> results;
            _redis->zrevrange(key, start, stop, back_inserter(results));
            LOG(LogLevel::DEBUG) << "ZREVRANGE found " << results.size() << " members";
            
            vector<T> converted;
            for (const auto& result : results) {
                converted.push_back(fromString<T>(result));
            }
            return converted;
        }
    
        template<typename T>
        optional<double> zscore(const string& key, const T& member) {
            LOG(LogLevel::DEBUG) << "ZSCORE command - key: " << key << ", member: " << toString(member);
            auto result = _redis->zscore(key, toString(member));
            LOG(LogLevel::DEBUG) << "ZSCORE result: " << (result ? to_string(*result) : "not found");
            return result ? optional<double>(*result) : nullopt;
        }

        //范围查询 - 有序集合按分数范围查询
        template<typename T>
        vector<pair<T, double>> zrangebyscore(const string& key, double min, double max) {
            LOG(LogLevel::DEBUG) << "ZRANGEBYSCORE command - key: " << key << ", min: " << min << ", max: " << max;
            vector<pair<string, double>> results;
            
            // 使用区间对象而不是单独的 min, max
            _redis->zrangebyscore(key, 
                                sw::redis::BoundedInterval<double>(min, max, sw::redis::BoundType::CLOSED),
                                back_inserter(results));
            
            LOG(LogLevel::DEBUG) << "ZRANGEBYSCORE found " << results.size() << " members";
            
            vector<pair<T, double>> converted;
            for (const auto& item : results) {
                converted.emplace_back(fromString<T>(item.first), item.second);
            }
            return converted;
        }

        //其他操作
        bool ping() {
            LOG(LogLevel::DEBUG) << "PING command";
            bool result = _redis->ping() == "PONG";
            LOG(LogLevel::DEBUG) << "PING result: " << result;
            return result;
        }

        void flushall() {
            LOG(LogLevel::WARNING) << "FLUSHALL command - clearing all data";
            _redis->flushall();
            LOG(LogLevel::INFO) << "FLUSHALL completed";
        }

        // 析构函数
        ~Redis_Client() {
            LOG(LogLevel::INFO) << "Redis client destroyed";
        }
    };
    // 必须在某个 .cpp 文件中定义这些静态成员
    shared_ptr<Redis_Client> Redis_Client::_instance = nullptr;
    Redis_Client::Connection Redis_Client::_options = {};
    Lock_Module::Mutex Redis_Client::_instance_mutex;
}


#endif 